home *** CD-ROM | disk | FTP | other *** search
- // Sample AppleTalk adev resource
- // (C) 1994-1995 Stuart Cheshire <cheshire@cs.stanford.edu>
- //
- // You need to contact Apple to get an adev id assigned.
- // This file must be compiled into a code resource of type 'adev' with your id.
- // This resource file is then merged into the final adev file built by the
- // atlk project (See atlk.c)
- //
- // The main routine in assembly code here calls the three C routines below:
- // 1. doGetAdev indicates the available AppleTalk connection icons to display in
- // the Network Control Panel There is just one for the 'None' connection, but
- // other adevs may offer multiple connections -- eg. multiple serial ports --
- // in which case they are distinguished by an index in the low byte of d2
- // 2. doSelAdev is called when the user selects our icon
- // 3. doReSelAdev is called when the user double-clicks on our icon
- // Some of the parameters to the C routines are declared volatile to provide
- // call-by-value-return semantics, to allow the C code to easily return values
- // in registers without having to use even more nasty inline assembly code.
- // If your compiler doesn't honour volatile parameters you'll have to write
- // inline assembly code.
- //
- // You should also read the "Macintosh AppleTalkĀ® Connections Programmer's Guide"
- // available from Apple.
-
- #include <AppleTalk.h>
- #include "LAPEqu.h"
-
- #include "StuTypes.h"
- #include "adev.h"
-
- // *********************************************************************************
-
- local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name);
- local void doSelAdev(u_long volatile pram, u_long const d2);
- local void doReSelAdev(u_long volatile pram, u_long const d2);
-
- export void main(void)
- {
- asm {
- @0 move.l a4, -(sp) ; save A4
- lea @0, a4 ; set up global register
-
- cmpi.l #GetADEV, D0 ; Is this a GetADEV call?
- bne.s @1 ; If not, try the next one
-
- move.l a0, -(sp) ; If yes,
- move.l d2, -(sp) ; Push parameters on the stack
- move.l d1, -(sp)
- bsr doGetAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
- move.l (sp)+, a0
- bra.s @exit
-
- @1 cmpi.l #SelectADEV, D0 ; Is this a SelectADEV call?
- bne.s @2 ; If not, try the next one
-
- move.l d2, -(sp) ; If yes,
- move.l d1, -(sp) ; Push parameters on the stack
- bsr doSelAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
- bra.s @exit
-
- @2 cmpi.l #ReSelADEV, D0 ; Is this a ReSelADEV call?
- bne.s @exit ; If not, give up
-
- move.l d2, -(sp) ; If yes,
- move.l d1, -(sp) ; Push parameters on the stack
- bsr doReSelAdev ; and make the call
- move.l (sp)+, d1
- move.l (sp)+, d2
-
- @exit move.l (sp)+, a4 ; restore A4
- }
- }
-
- // *********************************************************************************
-
- enum { InterfaceActive = -1, InterfaceInactive = 0, NoMoreInterfaces = 1 };
-
- local u_short num_ports;
-
- local char doGetAdev(u_long const pram, u_long volatile d2, u_char *volatile name)
- {
- // If d2 is zero, then this is the first adev call, and we should do any
- // necessary initialization. As part of that initialization I set the high
- // order bytes d2 to be non-zero, so that on the next call I'll know that
- // I've already done the initialization. The low byte (byte 0) of d2 contains
- // a zero-based index to identify a particular port for adevs that support
- // multiple ports (e.g. Printer Port and Modem Port) -- so we return zero
- // the first time and increment it on subsequent calls. The choice of 0x00FFFF
- // as the chosen "non-zero value" for the high order bytes is because there's
- // a bug on Duos that makes them forget your chosen network selection when you
- // put the Duo to sleep and when it wakes up again it reverts to LocalTalk.
- // Putting 0xFFFF in the top word of the PRAM value seems to avoid the bug.
- // Don't ask me why.
- if (!d2)
- {
- d2 = 0x00FFFF00;
- // Do initialization here,
- // eg. count how many ports are available
- num_ports = 1;
- }
- else d2++;
-
- if ((d2 & 0xFF) >= num_ports) return(NoMoreInterfaces);
-
- // Give the name of the port identified by index (d2 & 0xFF)
- name = "\pNone";
-
- // Wierd magic required by the Network Control Panel
- if ((pram >> 8) == d2) return(InterfaceActive); else return(InterfaceInactive);
- }
-
- // *********************************************************************************
-
- local void doSelAdev(u_long volatile pram, u_long const d2)
- {
- // User has clicked on one of our icons, identified by d2
- // Stash this code in the high three bytes of the AppleTalk PRAM
- // so we'll know which port to open in the atlk resource
- pram = d2 << 8 | ADEV_ID;
- }
-
- // *********************************************************************************
-
- local void doReSelAdev(u_long volatile pram, u_long const d2)
- {
- // User has clicked again on our already selected icon
- // Can display dialog for options or configuration display here
- pram = d2 << 8 | ADEV_ID;
- }
-